using System;
using System.Security.Cryptography;
using System.Text;
using System.Linq;
using System.Collections.Generic;

namespace Octubre.Framework
{
	public class Application
	{
		//Configuraciones de aplicacion
		public static string PrivateSignature { get; set; }

		public static string HashPassword(string password)
		{
			return Convert.ToBase64String(
				SHA512.Create().ComputeHash(Encoding.Default.GetBytes(
				PrivateSignature + password
			)));
		}


		private static Storable CreateFrom (Type trecord, Type tentity)
		{
			var en = (Storable)Activator.CreateInstance(tentity);

			en.Id = new Guid(MD5.Create().ComputeHash(
				Encoding.Default.GetBytes(trecord.FullName)));

			return en;
		}

		private static Action<Storable> CreateSetup(Type trecord)
		{
			return delegate(Storable entity) {
				var method = trecord.GetMethod("Setup");
				var instance = Activator.CreateInstance(trecord);
				method.Invoke(instance,new object[] { entity });
			};
		}

		public static void Start ()
		{
			var records = (from asm in AppDomain.CurrentDomain.GetAssemblies ()
				from type in asm.GetTypes ()
				from iface in type.GetInterfaces ()
				where iface.IsGenericType 
				&& iface.GetGenericTypeDefinition () == typeof(Record<>)
				select new {
					Entity = CreateFrom (type, iface.GetGenericArguments().First()),
					Setup = CreateSetup (type),
					Type = type
				}).ToList();



			foreach (var item in records) {
				Database.StaticEntities.Add(item.Type,item.Entity);
			}

			foreach (var item in records) {
				item.Setup(item.Entity);
			}

			Database.Initialized = true;
			Database.Save(records.Select(x => x.Entity).ToArray());
		}

	}

	//(i.IsGenericType && i.GetGenericTypeDefinition () == typeof (IList<>)
}